}
}
+/**
+ * _st_create_texture_material:
+ * @src_texture: The CoglTexture for the material
+ *
+ * Creates a simple material which contains the given texture as a
+ * single layer.
+ */
+CoglHandle
+_st_create_texture_material (CoglHandle src_texture)
+{
+ static CoglHandle texture_material_template = COGL_INVALID_HANDLE;
+ CoglHandle material;
+
+ g_return_val_if_fail (src_texture != COGL_INVALID_HANDLE,
+ COGL_INVALID_HANDLE);
+
+ /* We use a material that has a dummy texture as a base for all
+ texture materials. The idea is that only the Cogl texture object
+ would be different in the children so it is likely that Cogl will
+ be able to share GL programs between all the textures. */
+ if (G_UNLIKELY (texture_material_template == COGL_INVALID_HANDLE))
+ {
+ static const guint8 white_pixel[] = { 0xff, 0xff, 0xff, 0xff };
+ CoglHandle dummy_texture;
+
+ dummy_texture =
+ cogl_texture_new_from_data (1, 1,
+ COGL_TEXTURE_NONE,
+ COGL_PIXEL_FORMAT_RGBA_8888_PRE,
+ COGL_PIXEL_FORMAT_ANY,
+ 4, white_pixel);
+
+ texture_material_template = cogl_material_new ();
+ cogl_material_set_layer (texture_material_template, 0, dummy_texture);
+ cogl_handle_unref (dummy_texture);
+ }
+
+ material = cogl_material_copy (texture_material_template);
+
+ cogl_material_set_layer (material, 0, src_texture);
+
+ return material;
+}
/*****
* Shadows
} StCornerSpec;
static CoglHandle
-create_corner_texture (StCornerSpec *corner)
+create_corner_material (StCornerSpec *corner)
{
CoglHandle texture;
cairo_t *cr;
{
LoadCornerData *data = datap;
- return create_corner_texture (data->corner);
+ return create_corner_material (data->corner);
}
/* To match the CSS specification, we want the border to look like it was
st_theme_node_lookup_corner (StThemeNode *node,
StCorner corner_id)
{
- CoglHandle texture;
+ CoglHandle texture, material;
char *key;
StTextureCache *cache;
StCornerSpec corner;
data.node = node;
data.corner = &corner;
texture = st_texture_cache_load (cache, key, ST_TEXTURE_CACHE_POLICY_NONE, load_corner, &data, NULL);
+ material = _st_create_texture_material (texture);
+ cogl_handle_unref (texture);
g_free (key);
- return texture;
+ return material;
}
static void
cogl_handle_unref (node->background_shadow_material);
if (node->border_texture != COGL_INVALID_HANDLE)
cogl_handle_unref (node->border_texture);
+ if (node->border_material != COGL_INVALID_HANDLE)
+ cogl_handle_unref (node->border_material);
if (node->border_shadow_material != COGL_INVALID_HANDLE)
cogl_handle_unref (node->border_shadow_material);
for (corner_id = 0; corner_id < 4; corner_id++)
- if (node->corner_texture[corner_id] != COGL_INVALID_HANDLE)
- cogl_handle_unref (node->corner_texture[corner_id]);
+ if (node->corner_material[corner_id] != COGL_INVALID_HANDLE)
+ cogl_handle_unref (node->corner_material[corner_id]);
_st_theme_node_init_drawing_state (node);
}
node->background_shadow_material = COGL_INVALID_HANDLE;
node->border_shadow_material = COGL_INVALID_HANDLE;
node->border_texture = COGL_INVALID_HANDLE;
+ node->border_material = COGL_INVALID_HANDLE;
for (corner_id = 0; corner_id < 4; corner_id++)
- node->corner_texture[corner_id] = COGL_INVALID_HANDLE;
+ node->corner_material[corner_id] = COGL_INVALID_HANDLE;
}
static void st_theme_node_paint_borders (StThemeNode *node,
node->border_texture = st_theme_node_render_gradient (node);
}
+ if (node->border_texture)
+ node->border_material = _st_create_texture_material (node->border_texture);
+ else
+ node->border_material = COGL_INVALID_HANDLE;
+
if (shadow_spec)
{
if (node->border_texture != COGL_INVALID_HANDLE)
}
}
- node->corner_texture[ST_CORNER_TOPLEFT] =
+ node->corner_material[ST_CORNER_TOPLEFT] =
st_theme_node_lookup_corner (node, ST_CORNER_TOPLEFT);
- node->corner_texture[ST_CORNER_TOPRIGHT] =
+ node->corner_material[ST_CORNER_TOPRIGHT] =
st_theme_node_lookup_corner (node, ST_CORNER_TOPRIGHT);
- node->corner_texture[ST_CORNER_BOTTOMRIGHT] =
+ node->corner_material[ST_CORNER_BOTTOMRIGHT] =
st_theme_node_lookup_corner (node, ST_CORNER_BOTTOMRIGHT);
- node->corner_texture[ST_CORNER_BOTTOMLEFT] =
+ node->corner_material[ST_CORNER_BOTTOMLEFT] =
st_theme_node_lookup_corner (node, ST_CORNER_BOTTOMLEFT);
}
static void
-paint_texture_with_opacity (CoglHandle texture,
- ClutterActorBox *box,
- guint8 paint_opacity)
+paint_material_with_opacity (CoglHandle material,
+ ClutterActorBox *box,
+ guint8 paint_opacity)
{
- if (paint_opacity == 255)
- {
- /* Minor: optimization use the default material if we can */
- cogl_set_source_texture (texture);
- cogl_rectangle (box->x1, box->y1, box->x2, box->y2);
- return;
- }
-
- CoglHandle material;
-
- material = cogl_material_new ();
- cogl_material_set_layer (material, 0, texture);
cogl_material_set_color4ub (material,
paint_opacity, paint_opacity, paint_opacity, paint_opacity);
cogl_set_source (material);
cogl_rectangle (box->x1, box->y1, box->x2, box->y2);
-
- cogl_handle_unref (material);
}
static void
int max_width_radius[4];
int corner_id;
ClutterColor border_color;
- CoglHandle material;
width = box->x2 - box->x1;
height = box->y2 - box->y1;
/* corners */
if (max_border_radius > 0)
{
- material = cogl_material_new ();
- cogl_material_set_color4ub (material,
- paint_opacity, paint_opacity,
- paint_opacity, paint_opacity);
- cogl_set_source (material);
-
for (corner_id = 0; corner_id < 4; corner_id++)
{
- if (node->corner_texture[corner_id] == COGL_INVALID_HANDLE)
+ if (node->corner_material[corner_id] == COGL_INVALID_HANDLE)
continue;
- cogl_material_set_layer (material,
- 0, node->corner_texture[corner_id]);
+ cogl_material_set_color4ub (node->corner_material[corner_id],
+ paint_opacity, paint_opacity,
+ paint_opacity, paint_opacity);
+ cogl_set_source (node->corner_material[corner_id]);
switch (corner_id)
{
break;
}
}
- cogl_handle_unref (material);
}
/* background color */
if (ey < 0)
ey = border_bottom; /* FIXME ? */
- material = cogl_material_new ();
- cogl_material_set_layer (material, 0, node->border_texture);
+ material = node->border_material;
cogl_material_set_color4ub (material,
paint_opacity, paint_opacity, paint_opacity, paint_opacity);
cogl_rectangles_with_texture_coords (rectangles, 9);
}
-
- cogl_handle_unref (material);
}
static void
&allocation,
paint_opacity);
- if (node->border_texture != COGL_INVALID_HANDLE)
+ if (node->border_material != COGL_INVALID_HANDLE)
{
/* Gradients and border images are mutually exclusive at this time */
if (node->background_gradient_type != ST_GRADIENT_NONE)
- paint_texture_with_opacity (node->border_texture, &allocation, paint_opacity);
+ paint_material_with_opacity (node->border_material, &allocation, paint_opacity);
else
st_theme_node_paint_sliced_border_image (node, &allocation, paint_opacity);
}
&background_box,
paint_opacity);
- paint_texture_with_opacity (node->background_texture, &background_box, paint_opacity);
+ paint_material_with_opacity (node->border_material, &background_box, paint_opacity);
}
}
node->background_texture = cogl_handle_ref (other->background_texture);
if (other->border_texture)
node->border_texture = cogl_handle_ref (other->border_texture);
+ if (other->border_material)
+ node->border_material = cogl_handle_ref (other->border_material);
for (corner_id = 0; corner_id < 4; corner_id++)
- if (other->corner_texture[corner_id])
- node->corner_texture[corner_id] = cogl_handle_ref (other->corner_texture[corner_id]);
+ if (other->corner_material[corner_id])
+ node->corner_material[corner_id] = cogl_handle_ref (other->corner_material[corner_id]);
}